﻿/**
 * @file service_context.hpp
 * @date 2021/04/25 14:11
 *
 * @author harrybao (harrybao@123u.com)
 *
 * @brief
 *
 * @version v1.0.0
 *
 * @copyright Copyright © 2021 All Rights Reserved 上海欢乐互娱网络科技有限公司
 *
 * @par history:
 * <table>
 * <tr><th>Date                     <th>Version     <th>Author <th>Description
 * <tr><td>2021/04/25 14:11         <td>1.0.0       <td>harrybao
 * <td>创建初始版本
 * </table>
 */

// #ifndef SERVICE_CONTEXT_H
// #define SERVICE_CONTEXT_H

#pragma once

#include <string>
#include <set>
#include "box/memory_allocator.hh"
#include "box/service_context.hh"
#include "service_tool.hpp"
#include "singleton.hpp"
#include "config/box_config.hh"

namespace guild_service {
namespace common {

/**
 * @brief 服务上下文
 *
 */
class service_context : public service_tool {
 public:
  using service_context_type = kratos::service::ServiceContext;
  using memory_allocator_type = kratos::service::MemoryAllocator;
  using box_config_type = kratos::config::BoxConfig;

  service_context(service_context_type* context)
      : service_tool(), m_context(context) {}

  service_context() : service_tool(), m_context(nullptr) {}

  virtual ~service_context() = default;

  /**
   * @brief 服务上下文运算符重载
   *
   * @return service_context_type* 服务上下文
   */
  service_context_type* operator->() const { return m_context; }
  
  /**
   * @brief 注册服务
   * 
   * @param service_name 服务名
   * @return true 注册成功
   * @return false 注册失败
   */
  bool RegisterService(const std::string &service_name) {
    if (IsServiceRegistered(service_name)) {
      return true;
    }
    return m_context->register_service(service_name);
  }
  
  /**
   * @brief 注销服务
   * 
   * @param service_name 服务名
   * @return true 注销成功
   * @return false 注销失败
   */
  bool UnregisterService(const std::string &service_name) {
    m_registered_service_name_set.erase(service_name);
    return m_context->unregister_service(service_name);
  }

  /**
   * @brief 服务是否已经注册过了
   * 
   * @param name 服务名
   * @return true 已注册
   * @return false 未注册
   */
  bool IsServiceRegistered(const std::string &name) const {
    return m_registered_service_name_set.count(name) > 0;
  }

 private:
  /// 服务上下文
  service_context_type* m_context;
  /// 已经注册的服务名
  std::set<std::string> m_registered_service_name_set;
};
}  // namespace common

/// 服务上下文单例
#define ServiceContextSingleton(...) \
  (*common::singleton<common::service_context>::instance(__VA_ARGS__))

/**
 * @brief 获取内存分配器
 *
 * @return common::service_context::memory_allocator_type& 内存分配器
 */
inline static common::service_context::memory_allocator_type& get_allocator() {
  return ServiceContextSingleton()->get_allocator();
}

/**
 * @brief 获取配置
 * 
 * @return common::service_context::box_config_type& 配置类
 */
inline static common::service_context::box_config_type& get_config() {
  return ServiceContextSingleton()->get_config();
}

/**
 * @brief 注册服务
 *
 * @param service_name 服务名
 * @return true 注册成功
 * @return false 注册失败
 */
inline static bool register_service(const std::string& service_name) {
  return ServiceContextSingleton().RegisterService(service_name);
}

/**
 * @brief 注销服务
 *
 * @param service_name 服务名
 * @return true 注销成功
 * @return false 注销失败
 */
inline static bool unregister_service(const std::string& service_name) {
  return ServiceContextSingleton().UnregisterService(service_name);
}

}  // namespace guild_service

// #endif  // SERVICE_CONTEXT_H